#include"mtk-calc-convert.h"

int main(int argc,char **args)
{
    FILE *fp_read=NULL;
    FILE *fp_write=NULL;
    line *lh=NULL; //line head
    line *cp=NULL; //current point
    line *np=NULL; //next point

    fp_read=fopen("test.txt","r");
    if(fp_read==NULL) {
        perror("file read not exit\n");
        return -1;
    }

    fp_write=fopen("rest.txt","a");
    if(fp_write==NULL) {
        perror("file write create failed\n");
        return -1;
    }

    cp=(line*)calloc(1,sizeof(line));
    cp->content=NULL;
    cp->content_len=0;
    cp->next=NULL;
    lh=cp;
    while(1) {
        np=(line*)calloc(1,sizeof(line));
        np->content=NULL;
        np->content_len=0;
        np->next=NULL;
        np->content_len=file_get_line(fp_read,&(np->content));
        line_fill_addr_data(np);
        cp->next=np;
        if(np->content_len==0) {
            debug("\033[34mend line of file\n\033[0m");
            break;
        }
        cp=np;
        np=NULL;
        debug("\033[34mnew node added\n\033[0m");
    }

    printf("\033[34mputs %d lines\n\033[0m",file_put_lines(fp_write,lh));

    free_line_head(lh);
    lh=NULL;

    fclose(fp_read);
    fclose(fp_write);

    return 0;
}

static int file_get_line(FILE *fp,char **s)
{
    int len=0;
    int i;
    char tc=0;

    tc=fgetc(fp);
    if(tc==EOF) {
        *s=NULL;
        len=0;
        return len;
    } else {
        fseek(fp,-1,SEEK_CUR);
    }

    while(1) {
        tc=fgetc(fp);
        ++len;
        if(tc!='\n' && tc!=EOF) {
            // ++len;
        } else {
            // ++len; //read \n
            break;
        }
    }
    *s=(char*)calloc(len+1,sizeof(char));
    fseek(fp,-len,SEEK_CUR);
    for(i=0;i<len;++i) {
        tc=fgetc(fp);
        (*s)[i]=tc;
    }
    (*s)[i]=0;
    debug("\033[31m[%4d]\033[0m",len);
    debug("%s",*s);
    debug("\033[34mline search over\n\033[0m");

    return len;
}

static void line_fill_addr_data(line *lp)
{
    char *addr_t=NULL;
    char *data_t=NULL;
    cmd *cp=NULL;
    cmd *pp=NULL; //preview p
    int data_cnt=0;

    lp->addr=NULL;
    lp->data=NULL;
    lp->data_cnt=0;

    if(lp->content_len==0) {
        debug("eof line, skip\n");
        return;
    } else if(lp->content[0]=='#') {
        debug("# comment line, skip\n");
        return;
    }

    addr_t=strstr(lp->content,"0x29");
    if(addr_t==NULL) {
        debug("no 0x29 found, skip\n");
        return;
    }

    addr_t=addr_t+4;
    data_t=strstr(addr_t,"0x");
    if(data_t==NULL) {
        perror("addr not found\n");
        return;
    } else {
        lp->addr=(cmd*)calloc(1,sizeof(cmd));
        lp->data=(cmd*)calloc(1,sizeof(cmd));
        cp=lp->data;
        cp->next=NULL; //for free last node in case more than one node
        strncpy(lp->addr->value,data_t,4);
        addr_t=addr_t+4;
    }

    debug("[reg data]");
    while(1) {
        data_t=strstr(addr_t,"0x");
        if(data_t==NULL) {
            break;
        } else {
            strncpy(cp->value,data_t,4);
            debug("%s,",cp->value);
            pp=cp;
            cp->next=(cmd*)calloc(1,sizeof(cmd));
            cp=cp->next;
            cp->next=NULL;
            addr_t=data_t+4;
            ++(lp->data_cnt);
        }
    }
    if(lp->data_cnt>0) {
        free(cp);
    }
    pp->next=NULL;
    debug("[cnt=%d]\n",lp->data_cnt);

    return;
}

static int file_put_lines(FILE *fp, line *lhp)
{
    int line_cnt=0;
    line *cp=NULL;
    cmd *dcp=NULL;
    cp=lhp->next;

    while(cp && cp->content_len!=0) {

        if(cp->data_cnt!=0) {
            fprintf(fp,"{%s, %d, {",cp->addr->value,cp->data_cnt);

            dcp=cp->data;
            while(dcp) {
                fputs(dcp->value,fp);
                if(dcp->next) {
                    fputs(", ",fp);
                } else {
                    fputs("}}\n",fp);
                }
                dcp=dcp->next;
            }
        }

        cp=cp->next;
        ++line_cnt;
    }

    return line_cnt;
}

static void free_cmd(line *lp)
{
    cmd *cp=NULL;
    cmd *np=NULL;
    free(lp->addr);
    cp=lp->data;
    while(cp) {
        np=cp->next;
        free(cp);
        cp=np;
    }
}

static void free_line_head(line *lhp)
{
    line *cp;
    line *np;

    cp=lhp;
    np=cp->next;

    while(cp!=NULL) {
        if(np!=NULL) {
            free(cp->content);
            free_cmd(cp);
            free(cp);
            cp=np;
            np=cp->next;
        } else { //free head
            free(cp->content);
            free(cp);
            cp=NULL;
        }
    }

    return;
}
